module demo (
    input           clk,      //输入时钟信号
    input           rst_n,    //输入复位信号
    input   [3:0]   i_data,   //输入4位宽的i_data
    input   [3:0]   q_data,   //输入4位宽的q_data
    input           ready_in,
    input   [1:0]   sel,
    output  [4:0]   out_data, //输出5位宽的out_data
    output          ready_out     
);

    reg [3:0] i_data_reg;
    reg [3:0] q_data_reg;
    reg [3:0] out_data_reg;

    reg [3:0] cnt;

    //计数器
    always @(posedge clk or negedge rst_n) begin  //边沿触发事件，只有当信号发生特定变化的时候执行
        if(!rst_n)                                //如果非rst_n的条件成立
            cnt<=4'b0;                            //则向cnt非阻塞型赋值二进制0                         
        
        else if(cnt==4'd8)                           //此处设计计数值，计数从0开始，计数到9，则计数到8结束
            cnt<=4'b0;
        
        else 
            cnt<=cnt+1'b1;                        //否则cnt计数加一
    end

    //reg in
    always @(posedge clk or negedge rst_n) begin  //边沿触发事件，只有当信号发生特定变化的时候执行
        if(!rst_n)                                 //如果非rst_n
            i_data_reg<=4'd0;                      //则向i_data_reg非阻塞型赋值二进制0 
        else if(cnt==4'd4)                         //如果cnt=4
            i_data_reg<=4'd3;                      //则向i_data_reg非阻塞型赋值二进制3
        else if(ready_in)
            i_data_reg<=i_data;
    end
    always @(posedge clk or negedge rst_n) begin   //同上
        if(!rst_n)
            q_data_reg<=4'd0;
        else if(cnt==4'd4)
            q_data_reg<=4'd3;
        else if(ready_in)
            q_data_reg<=q_data;
    end  

//-------------------------------------写法1------------------------------------------//
/*
    //MUX
    always @(*) begin
        case (sel)
            2'b00:  out_data_reg = i_data_reg;             //当sel=0时，out_data_reg 赋值 i_data_reg;
            2'b01:  out_data_reg = i_data_reg * q_data_reg;//当sel=1时，out_data_reg 赋值 i_data_reg 乘 q_data_reg
            2'b10:  out_data_reg = i_data_reg & q_data_reg;//当sel=2时，out_data_reg 赋值 i_data_reg 与 q_data_reg
            2'b11:  out_data_reg = i_data_reg && q_data_reg;//当sel=3时，out_data_reg 赋值 i_data_reg 和 q_data_reg
            default:;
        endcase
    end

    assign out_data = out_data_reg;
    assign ready_out = ready_in;
*/

//-------------------------------------写法2------------------------------------------//

    //MUX
    assign out_data = (sel==2'b00) ?  i_data_reg :                  //同上，使用了condition？true：false语句
                      (sel==2'b01) ? (i_data_reg * q_data_reg) :
                      (sel==2'b10) ? (i_data_reg & q_data_reg) :
                                     (i_data_reg && q_data_reg);
    assign ready_out = ready_in;

endmodule